<?

class db_redis
{
	/**
	 * @var Predis_Client
	 */
	private static $handle;

	private static $space;
	
	private static $php_api = true;

	/**
	 * @return Predis_connection
	 */
	public static function connection()
	{
		if ( !self::$handle )
		{
			if ( class_exists('Redis') )
			{
				self::$handle = new Redis();
				self::$php_api = false;
				self::$handle->connect( config::all()->redis['host'], config::all()->redis['port'] );
			}
			else
			{
				self::$handle = new Predis_Client( config::get('redis') );
			}
			
			self::$space = config::all()->redis['space'];
		}

		return self::$handle;
	}

	public static function reconnect()
	{
		if ( self::$php_api )
		{
			self::$handle = new Redis();
			self::$handle->connect( config::all()->redis['host'], config::all()->redis['port'] );
		}
		else
		{
			self::$handle = new Predis_Client( config::get('redis') );
		}
	}

	public static function set( $key, $val )
	{
		if ( is_array($val) ) $val = serialize($val);
		return self::connection()->set(self::$space . $key, $val);
	}

	public static function get( $key )
	{
		$data = self::connection()->get(self::$space . $key);
		if ( ($val = unserialize($data)) !== false ) return $val;
		
		return $data;
	}

	public static function del( $key )
	{
		return self::connection()->del(self::$space . $key);
	}

	public static function inc( $key, $amount = 1 )
	{
		return self::connection()->incrby(self::$space . $key, $amount);
	}

	public static function dec( $key, $amount = 1 )
	{
		return self::connection()->decrby(self::$space . $key, $amount);
	}

	public static function expire( $key, $seconds )
	{
		return self::connection()->expire(self::$space . $key, $seconds);
	}

	# Lists
	public static function list_get( $key, $limit = 50, $offset = 0 )
	{
		$start = $offset;
		$end = $start + $limit;

		if ( !$list = self::connection()->lrange(self::$space . $key, $start, $end) ) return array();
		foreach ( $list as $s ) $r[] = is_numeric($s) ? $s : unserialize($s);

		return $r;
	}

	public static function list_remove_item( $key, $value, $count = 0 )
	{
		self::connection()->lrem(self::$space . $key, $count, is_numeric($value) ? $value : serialize($value) );
	}

	public static function list_push_item( $key, $value, $if_exists = false )
	{
		$method = $if_exists ? 'lpushx' : 'lpush';
		self::connection()->{$method}(self::$space . $key, is_numeric($value) ? $value : serialize($value) );
	}

	public static function list_trim( $key, $start, $stop )
	{
		self::connection()->ltrim(self::$space . $key, $start, $stop );
	}

	public static function hash_inc( $key, $field, $incr_by = 1 )
	{
		return self::connection()->hincrby(self::$space . $key, $field, $incr_by);
	}
	
	public static function hash_dec( $key, $field, $by = 1 )
	{
		return self::connection()->hdecrby(self::$space . $key, $field, $by);
	}
	
	public static function hash_set( $key, $field, $value )
	{
		return self::connection()->hset(self::$space . $key, $field, $value);
	}
	
	public static function hash_get( $key, $field )
	{
		$data = self::connection()->hget(self::$space . $key, $field);
		return $data;
	}
	
	public static function hash_del( $key, $field )
	{
		$data = self::connection()->hdel(self::$space . $key, $field);
		return $data;
	}
	
	public static function hash_get_all( $key )
	{
		$data = self::connection()->hgetall(self::$space . $key);
		return $data;
	}
}